package br.com.android.aluno.comunicacao;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Map;

import android.text.Html;
import android.util.Log;

public class HttpNormalImpl extends Http {
	
	@Override
	public final String downloadArquivo(String url) {
		Log.i(ConstantesComunicacao.LOG_COM, "Http.downloadArquivo: " + url);
		
		try {
			URL u = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			
			//configura a requisicao para get
//			conn.setRequestProperty("Request-Method", "GET");
			conn.setRequestMethod("GET");
			conn.setDoInput(true);
			conn.setDoOutput(false);
			conn.connect();
			
			InputStream in = conn.getInputStream();
			String arquivo = readString(in);
			
			conn.disconnect();
			
			return arquivo;
			
		} catch (MalformedURLException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		} catch (IOException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		}
		
		return null;
	}

	@Override
	public final byte[] downloadImagem(String url) {
		Log.i(ConstantesComunicacao.LOG_COM, "Http.downloadArquivo: " + url);
		
		try {
			URL u = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			
			//configura a requisicao para GET
			conn.setRequestProperty("Request-Method", "GET");
			conn.setDoInput(true);
			conn.setDoOutput(false);
			conn.connect();
			
			InputStream in = conn.getInputStream();
			byte[] bytes = readBytes(in);
			
			Log.i(ConstantesComunicacao.LOG_COM, "imagem retornada com: " + bytes.length + " bytes");
			
			conn.disconnect();
			
			return bytes;
			
		} catch (MalformedURLException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		} catch (IOException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		}
		
		return null;
	}
	
	@Override
	public String doPost(String url, Map<String, String> params) throws ConnectException {
		return doPost(url, params, "");
	}
	
	public String doPost(String url, Map<String, String> params, String contentType) throws ConnectException{
		
		String queryString = getQueryString(params);
		String texto = doPost(url, queryString, contentType);
		
		return texto;
	}
	
	@Override
	public String doPost(String url, String params) throws ConnectException {
		return doPost(url, params, "");
	}
	
	public String doPost(String url, String params, String contentType) throws ConnectException{
		try {
//			Log.i(ConstantesComunicacao.LOG_COM, url + "?" + params);
			URL u = new URL(url);
			
			HttpURLConnection connection = (HttpURLConnection) u.openConnection();
			connection.setRequestMethod(ConstantesComunicacao.RESQUEST_METHOD_POST);
			connection.setRequestProperty("User-Agent", ConstantesComunicacao.HTTP_AGENT);
			connection.setRequestProperty("Cache-Control", "no-cache");
			connection.setRequestProperty("Connection", "close");
			
			if(!contentType.equals("")){
				connection.setRequestProperty("Content-Type", contentType);
			}
			
			connection.setDoInput(true);
			connection.setDoOutput(true);
//			connection.setConnectTimeout(10*1000);
			connection.connect();
						
			OutputStream out = connection.getOutputStream();
			
			byte[] paramsBytes = params.getBytes(ConstantesComunicacao.CODIFICACAO_UTF8);
			out.write(paramsBytes);
			out.flush();
			out.close();
			
			InputStream in = connection.getInputStream();
			
			//Banco esta no padrao ASCII, deve ser mudado para UTF-8 e remover a linha abaixo
			String resp = Html.fromHtml(readString(in)).toString();
//			String resp = readString(in);
			
			connection.disconnect();
			
			return resp;
			
		} catch (MalformedURLException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		} catch (ProtocolException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		} catch (UnsupportedEncodingException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		} catch (IOException e) {
			Log.e(ConstantesComunicacao.LOG_COM, e.getMessage(), e);
		}
		
		return "";
	}
	
	/**
	 * Transforma o hashmap em uma query string fazer o post
	 * 
	 * @param params
	 * @return
	 */
	private String getQueryString(Map<String, String> params) {
		if(params == null || params.size() == 0){
			return null;
		}
		
		String urlParams = null;
		Iterator<String> e = (Iterator<String>) params.keySet().iterator();
		
		while(e.hasNext()){
			String chave = (String) e.next();
			Object objValor = params.get(chave);
			String valor = objValor.toString();
			
			urlParams = urlParams == null ? "" : urlParams + "&";
			urlParams += chave + "=" + valor;
		}
		
		return urlParams;
	}

	/**
	 * Faz a leitura byte-a-byte da InputStream e coloca 
	 * em uma Stream de saida (ByteArrayOutputStream), 
	 * transformando posteriormente num array de bytes.
	 * 
	 * @param in
	 * @return
	 * @throws IOException 
	 */
	private byte[] readBytes(InputStream in) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		
		try {
			byte[] buffer = new byte[1024];
			int len;
			
			while((len = in.read(buffer)) > 0){
				bos.write(buffer, 0, len);
			}			
			
			byte[] bytes = bos.toByteArray();
			return bytes;
			
		} finally{
			bos.close();
			in.close();
		}
	}
	
	/**
	 * Faz a leitura o do texto da InputStream retornada
	 * 
	 * @param in
	 * @return
	 * @throws IOException 
	 */
	private String readString(InputStream in) throws IOException {		
		byte[] bytes = readBytes(in);
		String texto = new String(bytes);
		
		return texto;
	}
}
